﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameLib.Utils;

namespace GameLib.WorldMap
{
	public struct MapVertex : IEquatable<MapVertex>
	{
		public GameVector Location;

		public MapVertex(GameVector loc)
		{
			Location = loc;
		}

		public MapVertex(int x, int y)
		{
			Location.X = x;
			Location.Y = y;
		}

		public int X
		{
			get { return Location.X; }
		}

		public int Y
		{
			get { return Location.Y; }
		}

		public IEnumerable<MapVertex> Neighbours
		{
			get
			{
				yield return new MapVertex(Location.X, Location.Y - 1);

				yield return new MapVertex(Location.X, Location.Y + 1);

				if (Location.X % 2 == 0 ^ Location.Y % 2 == 0)
				{
					yield return new MapVertex(Location.X - 1, Location.Y);
				}
				else
				{
					yield return new MapVertex(Location.X + 1, Location.Y);
				}
			}
		}

		public bool IsNeighbour(MapVertex other)
		{
			return IsNeighbours(this, other);
		}

		public bool IsWithinMapBounds(Map map)
		{
			return X >= 0 && X < map.Width && Y >= 0 && Y < map.GetColumnHeight(X);
		}

		public static bool IsNeighbours(MapVertex vertA, MapVertex vertB)
		{
			if (vertA.Location.X == vertB.Location.X)
			{
				return (vertA.Location.Y == vertB.Location.Y + 1) || (vertA.Location.Y == vertB.Location.Y - 1);
			}
			else if (vertA.Location.Y == vertB.Location.Y)
			{
				if (vertA.Location.X % 2 == 0 ^ vertA.Location.Y % 2 == 0)
					return vertB.Location.X == vertA.Location.X - 1;
				else
					return vertB.Location.X == vertA.Location.X + 1;
			}
			else
			{
				return false;
			}
		}

		public static bool operator ==(MapVertex vertA, MapVertex vertB)
		{
			return vertA.Location == vertB.Location;
		}

		public static bool operator !=(MapVertex vertA, MapVertex vertB)
		{
			return vertA.Location != vertB.Location;
		}

		public static explicit operator MapVertex(GameVector location)
		{
			return new MapVertex(location);
		}

		public override bool Equals(object obj)
		{
			if (obj is MapVertex)
				return this == (MapVertex)obj;
			else
				return false;
		}

		public override int GetHashCode()
		{
			return Location.GetHashCode();
		}

		#region IEquatable<MapVertex> Members

		public bool Equals(MapVertex other)
		{
			return this == other;
		}

		#endregion
	}

}
